﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Collections;
using System.Windows.Data;
using System.Collections.ObjectModel;

namespace OpenLightGroup.Common.UserManagement
{
    public partial class UserRolesManager : UserControl
    {

        private ObservableCollection<string> _roles = new ObservableCollection<string>();

        private ObservableCollection<string> _availableRoles = new ObservableCollection<string>();

        private ObservableCollection<string> _userRoles = new ObservableCollection<string>();

        public UserRolesManager()
        {
            InitializeComponent();
            this.Loaded += new RoutedEventHandler(UserRolesManager_Loaded);
            this.AddRoleButton.Click += new RoutedEventHandler(AddRoleButton_Click);
            this.RemoveRoleButton.Click += new RoutedEventHandler(RemoveRoleButton_Click);
        }

        void RemoveRoleButton_Click(object sender, RoutedEventArgs e)
        {

            foreach (string selectedRole in this.UserRolesListBox.SelectedItems)
            {
                this._userRoles.Remove(selectedRole);

                this._availableRoles.Add(selectedRole);
            }

            this.User.Roles = this._userRoles.ToArray();



            //string selectedRole = this.UserRolesListBox.SelectedItem.ToString();

            //this._userRoles.Remove(selectedRole);

            //this.User.Roles = this._userRoles.ToArray();

            //this._availableRoles.Add(selectedRole);
        }

        void AddRoleButton_Click(object sender, RoutedEventArgs e)
        {

            foreach (string selectedRole in this.AvailableRolesListBox.SelectedItems)
            {
                this._userRoles.Add(selectedRole);

                this._availableRoles.Remove(selectedRole);
            }
            // string selectedRole = this.AvailableRolesListBox.SelectedItem.ToString();

            this.User.Roles = this._userRoles.ToArray();



        }

        void UserRolesManager_Loaded(object sender, RoutedEventArgs e)
        {
            var ctx = new Web.UserManagementContext();

            ctx.Load<Web.Role>(ctx.GetRolesQuery(), GetRolesCompleted, null);

            this.AvailableRolesListBox.SetBinding(ListBox.ItemsSourceProperty, new Binding() { Source = _availableRoles });

            this.UserRolesListBox.SetBinding(ListBox.ItemsSourceProperty, new Binding() { Source = _userRoles });

        }

        private void GetRolesCompleted(System.ServiceModel.DomainServices.Client.LoadOperation<Web.Role> obj)
        {

            _roles.Clear();

            obj.Entities.ToList().ForEach((r) => _roles.Add(r.Name));

            //if (User == null)
            //{
            //    _availableRoles.Clear();
            //    _roles.ToList().ForEach((r) => _availableRoles.Add(r));
            //}

            IEnumerable<string> roles = null;
           
            if (this.User != null)
                roles = this.User.Roles;

            UpdateRoleLists(this, roles);
        }

        public Web.User User
        {
            get { return (Web.User)GetValue(UserProperty); }
            set { SetValue(UserProperty, value); }
        }

        // Using a DependencyProperty as the backing store for User.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty UserProperty =
            DependencyProperty.Register("User", typeof(Web.User), typeof(UserRolesManager), new PropertyMetadata(UpdateUser));




        private static void UpdateUser(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var ctrl = (UserRolesManager)d;

            var  user = e.NewValue as Web.User;

            if (user != null)
                UpdateRoleLists(ctrl, user.Roles);


            //if (e.NewValue != null && (e.NewValue as Web.User).Roles != null)
            //{
            //    IEnumerable<string> userRoles = (e.NewValue as Web.User).Roles;

            //    //ctrl.UserRolesListBox.ItemsSource = userRoles;

            //    ctrl._userRoles.Clear();

            //    userRoles.ToList().ForEach((r) => ctrl._userRoles.Add(r));

            //    ctrl._availableRoles.Clear();

            //    foreach (var item in ctrl._roles)
            //    {
            //        if (userRoles.Contains(item) == false)
            //        {
            //            ctrl._availableRoles.Add(item);
            //        }
            //    }
            //}
            //else
            //{
            //    ctrl._userRoles.Clear();

            //    ctrl._availableRoles.Clear();

            //    ctrl._availableRoles.ToList().ForEach((r) => ctrl._roles.Add(r));


            //}

        }

        private static void UpdateRoleLists(UserRolesManager ctrl, IEnumerable<string> userRoles)
        {
            if (userRoles != null && userRoles.Count() > 0)
            {
           
                //ctrl.UserRolesListBox.ItemsSource = userRoles;

                ctrl._userRoles.Clear();

                userRoles.ToList().ForEach((r) => ctrl._userRoles.Add(r));

                ctrl._availableRoles.Clear();

                foreach (var item in ctrl._roles)
                {
                    if (userRoles.Contains(item) == false)
                    {
                        ctrl._availableRoles.Add(item);
                    }
                }

            }
            else
            {
                ctrl._userRoles.Clear();

                ctrl._availableRoles.Clear();

                ctrl._roles.ToList().ForEach((r) => ctrl._availableRoles.Add(r));

                //ctrl._availableRoles.ToList().ForEach((r) => ctrl._roles.Add(r));


            }

        }

        //public IEnumerable<string> AvailableRoles
        //{
        //    get { return (IEnumerable<string>)GetValue(AvailableRolesProperty); }
        //    set { SetValue(AvailableRolesProperty, value); }
        //}

        //// Using a DependencyProperty as the backing store for AvailableRoles.  This enables animation, styling, binding, etc...
        //public static readonly DependencyProperty AvailableRolesProperty =
        //    DependencyProperty.Register("AvailableRoles", typeof(IEnumerable<string>), typeof(UserRolesManager), new PropertyMetadata(UpdateAvailableRoles));


        //private static void UpdateAvailableRoles(DependencyObject d, DependencyPropertyChangedEventArgs e)
        //{
        //    var ctrl = (UserRolesManager)d;

        //    ctrl.AvailableRolesListBox.SetBinding(ListBox.ItemsSourceProperty,  new Binding() { Source = e.NewValue as IEnumerable });

        //    //ctrl.AvailableRolesListBox.ItemsSource =;

        //}




        //public IEnumerable<string> UserRoles
        //{
        //    get { return (IEnumerable<string>)GetValue(UserRolesProperty); }
        //    set { SetValue(UserRolesProperty, value); }
        //}

        //// Using a DependencyProperty as the backing store for UserRoles.  This enables animation, styling, binding, etc...
        //public static readonly DependencyProperty UserRolesProperty =
        //    DependencyProperty.Register("UserRoles", typeof(IEnumerable<string>), typeof(UserRolesManager), new PropertyMetadata(UpdateUserRoles));

        //private static void UpdateUserRoles(DependencyObject d, DependencyPropertyChangedEventArgs e)
        //{

        //    var ctrl = (UserRolesManager)d;

        //    ctrl.UserRolesListBox.ItemsSource = e.NewValue as IEnumerable;
        //}



    }
}
